#ifndef SH_THREADPOOL_RUNNABLE_HPP
#define SH_THREADPOOL_RUNNABLE_HPP

#include "../base.hpp"
#include "../signal.hpp"

namespace sh {

struct Runnable : public noncopyable {
	Runnable() : autoDel_{true} {}
	virtual ~Runnable() = default;
	virtual void run() = 0;

	bool autoDelete() const { return autoDel_; }
	void setAutoDelete(bool autoDel) { autoDel_ = autoDel; }

	template<class Callable>
	static Runnable* create(Callable&& callable);

public:
	Signal<> finished;

private:
	struct GenericRunnable;
	bool autoDel_;
};

struct Runnable::GenericRunnable : public Runnable {
	template<class Callable>
	GenericRunnable(Callable&& callable) : Runnable{}, callback{std::forward<Callable>(callable)} { if(!callback) callback=[]{}; }
	void run() override { callback(); finished(); }

private:
	std::function<void()> callback;
};


template<class Callable>
inline Runnable* Runnable::create(Callable&& callable)
{
	return new GenericRunnable(callable);
}

} // ns sh

#endif // SH_THREADPOOL_RUNNABLE_HPP